//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet.Expressions
{
    class ParenthesizedExpression: Expression
    {
        internal static UnqualifiedExpressionBase UnfoldedParenthesisExpression(UnqualifiedExpressionBase expression)
        {
            Contract.Requires(expression != null);
            Contract.Ensures(Contract.Result<UnqualifiedExpressionBase>() != null);
            if (expression is ParenthesizedExpression)
            {
                var p =
                    new List<Expression>(((ParenthesizedExpression)expression).GetSubExpressions());
                if (p.Count == 1)
                    return UnfoldedParenthesisExpression(p[0]);
            }
            return expression;
        }
        internal static Expression UnfoldedParenthesisExpression(Expression expression)
        {
            Contract.Requires(expression != null);
            Contract.Ensures(Contract.Result<Expression>() != null);
            if (expression is ParenthesizedExpression)
            {
                var p =
                    new List<Expression>(((ParenthesizedExpression)expression).GetSubExpressions());
                if (p.Count == 1)
                    return UnfoldedParenthesisExpression(p[0]);
            }
            return expression;
        }

        public ParenthesizedExpression(Expression inner)
        {
            _inner = inner;
        }
        internal override Expression Transposed(Cell target)
        {
            return new ParenthesizedExpression(Inner.Transposed(target));
        }
#if DEBUG
        [ContractInvariantMethod]
// ReSharper disable UnusedMember.Global
        private void ObjectInvariant()
// ReSharper restore UnusedMember.Global
        {
            Contract.Invariant(Inner != null);
        }
#endif

        private readonly Expression _inner;
        public override string GetText(TextContext context)
        {
            return "(" + Inner.GetText(context) + ")";
        }
        public override IEnumerable<Expression> GetSubExpressions()
        {
            yield return Inner;
        }

        public override IEnumerable<IDependencyNode> GetPrecedents(EvaluationContext context)
        {
            return Inner.GetPrecedents(context);
        }

        protected override object GetObjectImp(EvaluationContext context)
        {
            return Inner.GetObject(context);
        }

        public override Expression Offset(CellRelativeAddress a)
        {
            return new ParenthesizedExpression(Inner.Offset(a));
        }

        public Expression Inner
        {
            get { return _inner; }
        }
    }
}
